package net.cyan.thunwind.dao;

import net.cyan.commons.util.BeanUtils;
import net.cyan.thunwind.annotation.Operation;

import java.lang.reflect.Method;

/**
 * 
 * @author camel
 * @date 2008-11-8
 */
public class OperationGenerator implements DaoContentGenerator
{
    public OperationGenerator()
    {
    }

    public final boolean generateContent(Method method, String[] parameterNames, Class c, StringBuilder buffer)
    {
        String operation = getOperation(method);
        if (operation != null)
        {
            if ("get".equals(operation) && method.getParameterTypes().length > 0 &&
                    method.getParameterTypes()[0] != Class.class)
            {
                Class returnType = BeanUtils.toClass(BeanUtils.getRealType(method.getGenericReturnType(), c));
                if (returnType != Object.class)
                {
                    String className = BeanUtils.getClassName(returnType);
                    buffer.append(className).append(" $result=(").append(className).append(")handler$$.")
                            .append(operation).append("(").append(className).append(".class,");

                    if (parameterNames.length == 1)
                    {
                        buffer.append(parameterNames[0]);
                    }
                    else
                    {
                        buffer.append("new Object[]{");
                        for (int i = 0; i < parameterNames.length; i++)
                        {
                            if (i > 0)
                                buffer.append(",");
                            buffer.append(parameterNames[i]);
                        }
                        buffer.append("}");
                    }

                    buffer.append(");\n");
                    return true;
                }
            }

            if (("save".equals(operation) || "add".equals(operation) || "delete".equals(operation) ||
                    "lock".equals(operation)) && method.getParameterTypes().length == 0)
                parameterNames = new String[]{"this"};

            if (method.getReturnType() != void.class)
                buffer.append(BeanUtils.getClassName(method.getReturnType())).append(" $result=");

            buffer.append("handler$$.").append(operation).append("(");

            for (int i = 0; i < parameterNames.length; i++)
            {
                if (i > 0)
                    buffer.append(",");
                buffer.append(parameterNames[i]);
            }

            buffer.append(");\n");

            return true;
        }
        return false;
    }

    protected String getOperation(Method method)
    {
        Operation operation = method.getAnnotation(Operation.class);
        return operation != null ? operation.value() :
                method.getDeclaringClass() == Dao.class ? method.getName() : null;

    }
}
